﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using nwrole.lib;

namespace nwrole.service
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    internal class ServiceManager : IServiceManager
    {
        protected List<ServiceManagerInstance> Instances = new List<ServiceManagerInstance>();

        // verifierar att servicemanagern är startad och svarar med rätt värden
        public Guid GetIdentifier ()
        {
            EventLogger.LogInformation(String.Format("ServiceManager.GetIdentifier ({0})", Id), "Providing service identifier.");
            return Id;
        }

        public Result InstantiatePlugin (Plugin plugin, Solution solution, Solution.Service service, Solution.Instance instance)
        {
            try
            {
                EventLogger.LogInformation(String.Format("ServiceManager.InstantiatePlugin ({0})", Id), String.Format("Creating instance of '{0}'", plugin.Id));

                if ((from i in Instances where i.Instance.Id == instance.Id select i).FirstOrDefault() != null)
                {
                    EventLogger.LogError(String.Format("ServiceManager.InstantiatePlugin ({0})", Id), String.Format("Instance '{0}' already started.", instance.Id));
                    return Result.InstanceAlreadyStarted;
                }

                ServiceManagerInstance serviceInstance = new ServiceManagerInstance(plugin, instance, service, solution);
                serviceInstance.StartInstance();
                Instances.Add(serviceInstance);

                EventLogger.LogInformation(String.Format("ServiceManager.InstantiatePlugin ({0})", Id), String.Format("Created instance of '{0}'", plugin.Id));
            }
            catch (Exception exception)
            {
                EventLogger.LogException(String.Format("ServiceManager.InstantiatePlugin ({0})", Id), exception);
                return Result.UnknownError;
            }
            return Result.Success;
        }

        public Result KillInstance (Guid instanceId)
        {
            try
            {
                EventLogger.LogInformation(String.Format("ServiceManager.KillInstance ({0})", Id), String.Format("Stopping instance '{0}'", instanceId));

                ServiceManagerInstance serviceInstance = (from i in Instances where i.Instance.Id == instanceId select i).FirstOrDefault();
                if (serviceInstance == null)
                {
                    EventLogger.LogError(String.Format("ServiceManager.KillInstance ({0})", Id), String.Format("Instance '{0}' not available.", instanceId));
                    return Result.InstanceUnavailable;
                }

                serviceInstance.StopInstance();
                Instances.Remove(serviceInstance);

                EventLogger.LogInformation(String.Format("ServiceManager.KillInstance ({0})", Id), String.Format("Stopped instance '{0}'", instanceId));
            }
            catch (Exception exception)
            {
                EventLogger.LogException(String.Format("ServiceManager.KillInstance ({0})", Id), exception);
                return Result.UnknownError;
            }
            return Result.Success;
        }

        #region Common
        private Guid Id;

        public ServiceManager (Guid id)
        {
            Id = id;
        }

        public void OnStart()
        {
            EventLogger.LogInformation(String.Format("ServiceManager.OnStart ({0})", Id), "ServiceManager starting");
            // ...
            EventLogger.LogInformation(String.Format("ServiceManager.OnStart ({0})", Id), "ServiceManager started");
        }

        public void OnStop ()
        {
            foreach (var instance in Instances)
            {
                try
                {
                    if (instance.State == ServiceManagerInstanceState.Running)
                    {
                        EventLogger.LogInformation(String.Format("ServiceManager.OnStop ({0})", Id), String.Format("Stopping instance '{0}'", instance.Instance.Id));
                        instance.StopInstance();
                        EventLogger.LogInformation(String.Format("ServiceManager.OnStop ({0})", Id), String.Format("Stopped instance '{0}'", instance.Instance.Id));
                    }
                }
                catch (Exception exception)
                {
                    EventLogger.LogException(String.Format("ServiceManager.OnStop ({0})", Id), exception);
                }
            }
        }
        #endregion
    }
}
